package ma.moliere.persistance.impl;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import ma.moliere.persistance.IGestionInscriptionPersistance;
import ma.moliere.persistance.oe.Inscription;
import ma.moliere.persistance.oe.Reglement;
import ma.moliere.persistance.oe.Rencontre;
import ma.moliere.transverse.Constantes;
import ma.moliere.transverse.utils.ReglementUtil;
import ma.moliere.transverse.vo.ReglementAffiche;

import org.apache.commons.collections.CollectionUtils;

public class GestionInscriptionPersistanceImpl implements IGestionInscriptionPersistance, Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = -5317627693516113487L;

	@PersistenceContext
	private EntityManager entityManager;

	@Override
	public Inscription ajouter(final Inscription inscription) {

		entityManager.persist(inscription);
		entityManager.clear();
		return inscription;

	}

	@Override
	public Inscription modifier(final Inscription inscription) {
		Inscription inscriptionmodifie = entityManager.merge(inscription);
		entityManager.clear();
		return inscriptionmodifie;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List < ReglementAffiche > rechercherReglements(final List < Long > ids) {
		final StringBuilder vRequete = new StringBuilder();
		vRequete.append(" SELECT reglement FROM Reglement reglement ");
		vRequete.append(" WHERE reglement.id IN(:ids)");

		final Query vQuery = entityManager.createQuery(vRequete.toString());
		vQuery.setParameter("ids", ids);
		final List < Reglement > resultats = vQuery.getResultList();
		final List < ReglementAffiche > resultatsfinals = new ArrayList < ReglementAffiche >();
		if (CollectionUtils.isNotEmpty(resultats)) {
			for (Reglement reg : resultats) {
				resultatsfinals.add(ReglementUtil.copieOeVersVo(reg));
			}
		}
		return resultatsfinals;
	}

	@SuppressWarnings(Constantes.UNCHECKED)
	@Override
	public List < Inscription > rechercherInscription(final List < String > matricules, final Long idAnnee) {

		final StringBuilder vRequete = new StringBuilder();
		vRequete.append(" SELECT inscription FROM Inscription inscription ");
		vRequete.append(" WHERE 1=1");
		if (idAnnee != null) {
			vRequete.append(" AND inscription.anneescolaire = :idAnnee");
		}
		if (CollectionUtils.isNotEmpty(matricules)) {
			vRequete.append(" AND inscription.matricule IN (:matricules) ");
		}

		final Query vQuery = entityManager.createQuery(vRequete.toString());
		if (idAnnee != null) {
			vQuery.setParameter("idAnnee", idAnnee);
		}
		if (CollectionUtils.isNotEmpty(matricules)) {
			vQuery.setParameter("matricules", matricules);
		}
		final List < Inscription > resultats = vQuery.getResultList();

		return resultats;
	}

	@Override
	public void modifierReglement(final ReglementAffiche reglement) {
		Reglement entite = ReglementUtil.copieVoVersOe(reglement);
		entityManager.merge(entite);
		entityManager.flush();

	}

	@Override
	public void ajouterRencontre(final Rencontre rencontre) {
		entityManager.persist(rencontre);
		entityManager.flush();

	}

	@Override
	public Inscription rechercherParId(final Long id) {
		Inscription inscritpion = entityManager.find(Inscription.class, id);
		entityManager.flush();
		return inscritpion;
	}

	@SuppressWarnings(Constantes.UNCHECKED)
	@Override
	public List < Inscription > rechercherInscriptionParClasseGrpsEtAnnees(final List < Long > idsClasse,
		final List < Long > idsgrp, final List < Long > idsAnnee) {
		final StringBuilder vRequete = new StringBuilder();
		vRequete.append(" SELECT inscription FROM Inscription inscription ");
		vRequete.append(" WHERE 1=1");
		if (CollectionUtils.isNotEmpty(idsAnnee)) {
			vRequete.append(" AND inscription.anneescolaire in (:idsAnnee)");
		}
		if (CollectionUtils.isNotEmpty(idsgrp)) {
			vRequete.append(" AND inscription.groupe in (:idsgrp)");
		}
		if (CollectionUtils.isNotEmpty(idsgrp)) {
			vRequete.append(" AND inscription.classe in (:idsClasse)");
		}

		final Query vQuery = entityManager.createQuery(vRequete.toString());
		if (idsAnnee != null) {
			vQuery.setParameter("idsAnnee", idsAnnee);
		}
		if (idsgrp != null) {
			vQuery.setParameter("idsgrp", idsgrp);
		}
		if (idsgrp != null) {
			vQuery.setParameter("idsClasse", idsClasse);
		}

		final List < Inscription > resultats = vQuery.getResultList();

		return resultats;
	}

	@Override
	public Inscription initialiserGroupe(final Inscription inscription) {
		final StringBuilder vRequete = new StringBuilder();
		vRequete.append(" SELECT COUNT(DISTINCT inscription) FROM Inscription inscription ");
		vRequete.append(" WHERE 1=1");
		vRequete.append(" AND  inscription.classe = :classe");
		final Query vQuery = entityManager.createQuery(vRequete.toString());
		vQuery.setParameter("classe", inscription.getClasse());
		vQuery.setLockMode(LockModeType.PESSIMISTIC_WRITE);
		Long count = ((Long) vQuery.getSingleResult());
		Long grp = (new Double(Math.ceil(count / 30))).longValue();

		return null;
	}

	@Override
	public ReglementAffiche ajouterReglement(final ReglementAffiche reglement) {
		Reglement entite = ReglementUtil.copieVoVersOe(reglement);
		entityManager.persist(entite);
		entityManager.clear();
		return ReglementUtil.copieOeVersVo(entite);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List < ReglementAffiche > rechercherReglementsParInscription(final List < Long > ids) {
		final StringBuilder vRequete = new StringBuilder();
		vRequete.append(" SELECT reglement FROM Reglement reglement ");
		vRequete.append(" WHERE reglement.inscriptionId IN(:ids)");

		final Query vQuery = entityManager.createQuery(vRequete.toString());
		vQuery.setParameter("ids", ids);

		final List < Reglement > resultats = vQuery.getResultList();
		final List < ReglementAffiche > resultatsfinals = new ArrayList < ReglementAffiche >();
		if (CollectionUtils.isNotEmpty(resultats)) {
			for (Reglement reg : resultats) {
				resultatsfinals.add(ReglementUtil.copieOeVersVo(reg));
			}
		}
		return resultatsfinals;
	}

}
